'use strict'

const cheerio = require('cheerio')
const { getHTML } = require('../lib/utils')

const uview = {}

let $ = null
let url = ''
let key = []
let subLabel = undefined // 多个组件

/**
 * 描述一个组件参数构成的对象，并返回
 * {
        name: '',               // 组件名字
        attributes: [{          // 组件属性
            attr: '',           // 属性名
            version: '',        // 兼容版本
            type: '',           // 属性类型
            valueType: '',      // 值类型
            options: [],        // 可选值 | 回调参数
            default: '',        // 默认值
            description: ''     // 属性描述
        }],
        snippets: '',           // 代码段
        description: '',        // 组件描述
        url: ''                 // 组件文档地址
    }
*/
function TagAst (v) {
    return {
        name: getTagName(),                 // 组件名字
        attributes: getTagAttr(v),           // 组件属性
        snippets: getTagSnippets(v),         // 代码段
        description: getTagDesc(),          // 组件描述
        url: getTagUrl()                    // 组件文档地址
    }
}

const getTagName = () => { return $('.theme-default-content h2').text().replace('# ', '') }

const getTagAttr = (v) => {
    let attr = []
    const tag = v.replace('u-', '')
    const flag = subLabel && subLabel.includes(tag)
    // props
    const props = $(`.theme-default-content h3[${flag ? `id*="${tag.replace(/(.+)-/, '')}-props"` : 'id*="props"'}]`).nextAll('table').eq(0).find('tbody').children()
    props.each((index, item) => {
        const children = $(item).children()
        attr.push({
            attr: $(children).eq(0).text().split(' ')[0],           // 属性名
            version: $(children).eq(0).find('.badge').text(),        // 兼容版本
            type: 'props',           // 类型
            valueType: $(children).eq(2).text().replace('\\', '|'),           // 类型
            options: $(children).eq(4).text().split(/[/\\]/).map(m => m.trim()).filter(k => k !== '-' ),        // 可选值
            default: $(children).eq(3).text(),                                          // 默认值
            description: $(children).eq(1).text().replace('(opens new window)', '').trim()     // 属性描述
        })
    })

    // events
    const events = $(`.theme-default-content h3[${flag ? `id*="${tag.replace(/(.+)-/, '')}-event"` : 'id*="event"'}]`).nextAll('table').eq(0).find('tbody').children()
    events.each((index, item) => {
        const children = $(item).children()
        attr.push({
            attr: $(children).eq(0).text().split(' ')[0],           // 属性名
            version: $(children).eq(0).find('.badge').text(),        // 兼容版本
            type: 'events',           // 类型
            options: [$(children).eq(2).text()], // 回调参数
            description: $(children).eq(1).text().replace('(opens new window)', '').trim()     // 属性描述
        })
    })
    return attr
}

const getTagSnippets = (v) => {
    if (subLabel && subLabel.includes(v.replace('u-', ''))) { return `<${v}></${v}>` }
    const snippets = $('.theme-default-content #基本使用').nextAll('div.language-html').eq(0).find('code').text()
    let snippetsString = JSON.stringify(snippets)
    if (/\<template\>/.test(snippetsString)) {
        snippetsString = snippetsString.match(/\<template\>\\n\\t(.+)\<\/template\>/)[1]
    }
    snippetsString = snippetsString.match(new RegExp(`<${v}([^~])*(</${v}>|/>)`))[0]
    return snippetsString
}

const getTagDesc = () => { return $('.theme-default-content p').first().text() }

const getTagUrl = () => { return url }

uview.collect = async (ctx, next) => {
    key = []
    subLabel = undefined
    const ctxUrl = ctx.request.query.url
    url = ctxUrl.replace(/\$(.+)\$/, '$1').replace(/(-.+).html/, '.html')
    subLabel = ctx.request.query.subLabel?.split(',')
    subLabel
    ?key = subLabel.map(v => 'u-' + v.replace(/([A-Z])/g, "-$1").toLowerCase())
    :key.push('u-' + url.match(/components\/(.+)\.html/)[1].replace(/([A-Z])/g, "-$1").toLowerCase())
    if (subLabel && /\$(.+)\$/.test(ctxUrl)) { key.unshift('u-' + ctxUrl.match(/components\/\$(.+)\$\.html/)[1].replace(/([A-Z])/g, "-$1").toLowerCase()) }
    if (url.includes('loadmore')) { url = url.replace('loadmore', 'loadMore') }
    const content = await getHTML(url)
    $ = cheerio.load(content.document)
    ctx.result = { content: {} }
    await key.forEach(v => {
        return Object.assign(ctx.result.content, { [v]: TagAst(v) })
    })
    return next()
}

module.exports = uview